package com.rankeiot.platform.service;

import com.rankeiot.core.Current;
import com.rankeiot.core.data.UserInfo;
import com.rankeiot.core.job.JobHandler;
import com.rankeiot.core.job.JobManager;
import com.rankeiot.core.job.JobMeta;
import com.rankeiot.platform.PlatformModule;
import com.rankeiot.platform.domain.JobInfo;
import com.rankeiot.platform.domain.JobLog;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 定时任务Handler
 * 支持集群部署
 * 记录日志
 *
 * @author desire
 */
@Component
public class PlatformJobHandler implements JobHandler {
    SqlToyLazyDao dao;

    public PlatformJobHandler(SqlToyLazyDao dao) {
        this.dao = dao;
    }

    @Override
    public boolean before(String taskName,Date next,boolean force) {
        long i;
        if(force){
            i = dao.execute()
                    .autoCommit(true)
                    .sql("UPDATE t_job_info SET last_time=NOW(),next_time = ? WHERE id=? AND enable=true")
                    .values(next, taskName)
                    .submit();
        }else {
            i = dao.execute()
                    .autoCommit(true)
                    .sql("UPDATE t_job_info SET last_time=NOW(),next_time = ? WHERE id=? AND enable=true AND (last_time IS NULL OR next_time IS NULL OR NOW()>=next_time)")
                    .values(next, taskName)
                    .submit();
        }
        return i > 0;
    }

    @Override
    public void after(String taskName, long startTime, Exception e) {
        UserInfo u = Current.user();
        String userName = "system";
        if (u != null) {
            userName = u.getUsername();
        }
        JobLog jl = new JobLog();
        if (e != null) {
            jl.setStatus("失败");
            jl.setErrorInfo(e.getMessage());
        } else {
            jl.setStatus("成功");
        }
        jl.setExecuteTime(new Date(startTime));
        jl.setTakeTime((System.currentTimeMillis() - startTime) / 1000);
        jl.setTaskId(taskName);
        jl.setServerId(PlatformModule.serverId);
        jl.setIp(PlatformModule.localhost);
        jl.setUserName(userName);
        dao.save(jl);

    }

    private void regJobInfos() {
        //注册任务信息到数据库
        Collection<JobMeta> jobs = JobManager.getJobs();
        if (jobs.size() == 0) {
            return;
        }
        List<JobInfo> jobInfoList = new ArrayList<>();

        List<HashMap> ids= dao.findBySql("select id from t_job_info",new HashMap<>());
        Set<String> idSet=new HashSet<>();
        for(Map m:ids){
            idSet.add(m.get("id").toString());
        }
        for (JobMeta jm : jobs) {
            if(idSet.contains(jm.getName())){
                continue;
            }
            JobInfo ji = new JobInfo();
            ji.setId(jm.getName());
            ji.setCron(jm.getCron());
            ji.setDescribe(jm.getDesc());
            ji.setTitle(jm.getTitle());
            jobInfoList.add(ji);
        }
        dao.saveOrUpdateAll(jobInfoList);
        dao.executeSql("update t_job_info set enable=true where enable is null", new String[0]);
    }
    @EventListener
    public void onApplicationStarted(ApplicationStartedEvent event){
        JobManager.setHandler(this);
        JobManager.initJobs(event);
        regJobInfos();
        JobManager.start();
    }
}
